using Moq;
using NUnit.Framework;
using Tycho.Grammar;
using Tycho.Parser.Peg;

namespace Tycho.UnitTests.Grammar {
    [TestFixture]
    public class IdentifierProductionEvaluatorSpecification {
        [Test]
        public void ShouldEvaluateToProductionForGivenIdentifier () {
            var evaluator = new IdentifierProductionCompilerEvaluator (null);

            IProduction prod = new Mock<IProduction>().Object;
            evaluator.Add ("a", prod);

            Assert.That (evaluator.EvaluateQuote (CreateQuotedIdentifier ("a")), Is.EqualTo (prod));
        }

        private static ITerm CreateQuotedIdentifier (string id) {
            return new IdentifierTerm(id, null);
        }

        [Test]
        public void ShouldThrowExceptionIfIdentifierForProductionNotFound () {
            var evaluator = new IdentifierProductionCompilerEvaluator (null);

            Assert.That (() => { evaluator.EvaluateQuote (CreateQuotedIdentifier ("a")); },
                         Throws.InstanceOf (typeof (NoSuchProductionException)));
        }

        [Test]
        public void ShouldThrowExceptionIfTermForProductionNotIdentifier () {
            var evaluator = new IdentifierProductionCompilerEvaluator (null);

            Assert.That (() => { evaluator.EvaluateQuote (new IntegerTerm (8, null)); },
                         Throws.InstanceOf (typeof (NoSuchProductionException)));
        }

        [Test]
        public void DefaultShouldReturnProductionPassedToConstructor () {
            IProduction prod = new Mock<IProduction>().Object;
            var evaluator = new IdentifierProductionCompilerEvaluator (prod);
            Assert.That (evaluator.Default, Is.EqualTo (prod));
        }
    }
}